import { PropType, computed, defineComponent, onMounted, reactive, ref, watch, watchEffect } from "vue";
import Radio from "../Radio";
import formFieldRef from "../../use/formFieldRef";

export interface RadioGroupProps {
    block?: boolean,
    name?: string,
    value?: any,
    modelValue?: any,
    disabled?: boolean,
    onChange?: (v: any) => void,
    data?: any,
    type?: 'radio' | 'checkbox',
    textField?: string,
    valueField?: string,
    stick?: boolean,
    asFormField?: boolean
}

export default defineComponent({
    props: {
        block: { type: Boolean as PropType<RadioGroupProps['block']> },
        name: { type: String as PropType<RadioGroupProps['name']> },
        value: { type: [String, Number, Boolean] as PropType<RadioGroupProps['value']> },
        modelValue: { type: [String, Number, Boolean] as PropType<RadioGroupProps['modelValue']>, default: undefined },
        disabled: { type: Boolean },
        data: { type: Array as PropType<RadioGroupProps['data']>},
        type: { type: String as PropType<RadioGroupProps['type']>},
        textField: { type: String as PropType<RadioGroupProps['textField']>},
        valueField: { type: String as PropType<RadioGroupProps['valueField']>},
        stick: { type: Boolean as PropType<RadioGroupProps['stick']>},
        asFormField: { type: Boolean as PropType<RadioGroupProps['asFormField']>, default: true }
    },
    emits: ['change', 'update:modelValue'],
    setup (props: RadioGroupProps, { emit }) {
        const classList = computed(() => ({
            'cm-radio-group': true,
            'cm-radio-group-stack': props.block,
            'cm-radio-group-stick': props.stick,
        }));
        const value = formFieldRef(props, emit);
        const thumbStyle = ref({});

        const wrap = ref<HTMLDivElement | null>(null);

        const _onChange = (checked: boolean, v: any) => {
            if (props.disabled) {
                return;
            }
            value.value = v;
            props.data.forEach((item: any) => {
                store[item[valueField]] = item[valueField] === v ? checked : false;
            });
            emit('change', v);
        };

        watch(() => value.value, (val) => {
            props.data.forEach((item: any) => {
                store[item[valueField]] = item[valueField] === val;
            });
        });

        const textField = props.textField ?? 'label';
        const valueField = props.valueField ?? 'value';

        const store = reactive({});
        props.data.forEach((item: any) => {
            store[item[valueField]] = item[valueField] === value.value;
        });

        onMounted(() => {
            watchEffect(() => {
                const val: any = value.value ?? "";
                let currentIndex: number = -1;
                for (let i = 0; i < props.data.length; i++) {
                    const item = props.data[i];
                    const checked = val === item[valueField];
                    checked ? currentIndex = i : false;
                }

                if (wrap.value) {
                    const eles = wrap.value.querySelectorAll('.cm-radio');

                    const ele = eles[currentIndex];
                    if (!ele) {
                        return;
                    }
                    const rect = ele.getBoundingClientRect();
                    const wrapRect = wrap.value.getBoundingClientRect();
                    const left = rect.left - wrapRect.left;
                    const width = rect.width;
                    const ret = {
                        width: `${width}px`,
                        left: `${left}px`
                    };
                    thumbStyle.value = ret;
                }
            });
        });

        return () => <div class={classList.value} ref={wrap}>
            {
                props.stick
                    ? <div class="cm-radio-group-thumb" style={thumbStyle.value}></div>
                    : null
            }
            {
                props.data.map((item: any) => {
                    return <Radio disabled={props.disabled || item.disabled} type={props.type || 'radio'} value={item[valueField]} v-model={store[item[valueField]]} label={item[textField]} onChange={_onChange}></Radio>;
                })
            }
        </div>;
    }
});
